1、介绍
rgw lifecycle功能,也叫rgw生命周期功能,简单的理解就是我们对rgw bucket设置一个策略,这个策略规定bucket里面的数据何时过期,从而将过期的对象删掉或转移到其他地方。
目前12版本只支持将到期的数据对象删除掉,后面可能会增加把到期的数据对象转移到其他地方(比如N版里面加入的STORAGE CLASS功能)。
2、配置
重点:目前只能通过在rgw客户端使用api针对bucket设置(lifecycle规则作用在bucket上),只对该bucket里面的数据对象生效。管理侧(比如radosgw-admin)不支持设置bucket lc。
下面使用python3的boto3库来设置(使用s3cmd setlifecycle命令也可以),提前准备好一个rgw用户,并使用这个用户创建一个名为bk01的bucket。
设置lifecycle脚本内容:
[root@ceph01 ~]# cat lc.py 
import boto3
endpoint = "http://192.168.10.31:9001"    # rgw的访问地址
key = "NJ2VSBLRJ8Q7S0UYCWXE"    # rgw用户的access key
secret = "ElqXBaBsGOGDfzhRv4jBg9CXhY6xRAsv6A0A0Ru8"    # rgw用户的secret key
bucket = "bk01"    # rgw bucket名称
s3 = boto3.client('s3', aws_access_key_id=key, aws_secret_access_key=secret, endpoint_url=endpoint)
rule = {
          'Rules': [{                    #  设置过期规则部分
               'Expiration': {        
                    'Days': 1                # 过期时间,只能以天为单位
                },
                'ID': 'delete-anythings-after-one-day',     # 唯一的id,也可以使用一些字符串来说明此规则的大致含义
                'Status': 'Enabled',    
                'Prefix': ''                      # 对象的前缀,空字符串表示对所有对象起作用
         }],
}
s3.put_bucket_lifecycle(Bucket=bucket, LifecycleConfiguration=rule)
print(s3.get_bucket_lifecycle(Bucket=dev_bucket))
执行脚本:
[root@ceph01 ~]# python3 lc.py 
{'ResponseMetadata': {'RequestId': 'tx00000000000000000004e-005ebb6bad-3729-default', 'HostId': '', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amz-request-id': 'tx00000000000000000004e-005ebb6bad-3729-default', 'content-type': 'application/xml', 'content-length': '250', 'date': 'Wed, 13 May 2020 03:38:21 GMT'}, 'RetryAttempts': 0}, 'Rules': [{'Expiration': {'Days': 1}, 'ID': 'delete-anythings-after-one-day', 'Prefix': '', 'Status': 'Enabled'}]}
其中 ‘HTTPStatusCode’: 200表示设置成功。
注意:一个bucket对于相同的规则只支持设置一次,比如:
[    #  设置过期规则部分
    {                    
                   'Expiration': {        
                        'Days': 1                                # 过期时间,只能以天为单位
                    },
                    'ID': 'delete-anythings-after-one-day',     # 唯一的id,也可以使用一些字符串来说明此规则的大致含义
                    'Status': 'Enabled',    
                    'Prefix': ''                                  # 对象的前缀,空字符串表示对所有对象起作用
    },
    {                    
                   'Expiration': {        
                        'Days': 2                                # 过期时间,只能以天为单位
                    },
                    'ID': 'delete-anythings-after-two-day',     # 唯一的id,也可以使用一些字符串来说明此规则的大致含义
                    'Status': 'Enabled',    
                    'Prefix': ''                                  # 对象的前缀,空字符串表示对所有对象起作用
    },
]
这个rule就是有问题的,因为该rule要求1天之后对象过期,又要求对象两天之后过期,冲突了。
增加筛选对象过滤条件
通过Filter字段来实现:
rule = {
         'Rules': [{
            'Expiration': {        
                    'Days': 1
               },
            'ID': 'delete-anythings-after-one-day', 
            'Filter': {    // 筛选对象的过滤条件
                       'Tag': {    
                            // 这里的tag表示rgw数据对象的tagging,也可以通过api去设置和获取,存储在其head对象的xattr中
                            // 后续lc进程执行的时候,就会结合Prefix和Tag的设置,来判断对象是否符合该条件,不符合就会跳过
                             'Key': 'color',
                             'Value': 'red'
                         }
                   },
              'Status': 'Enabled',    
              'Prefix': ''
         }],
}
在N版之前使用tagging来筛选对象有个问题:比如有两个rule,rule1规定包含tag1:val1的对象在1天之后被删除,rule2规定包含tag2:val2的对象在2天之后被转移到其他地方。如果有一个对象同时包含tag1:val1和tag2:val2这两个tagging,那lc线程的行为会让人比较迷惑,这个pr:https://github.com/ceph/ceph/pull/35002/files,规定了只有full match tagging时才执行对应的操作(删除或转移)。
3、查看/删除
查看lifecycle接口:
s3.get_bucket_lifecycle(Bucket=dev_bucket)
删除lifecycle接口:
s3.delete_bucket_lifecycle(Bucket=dev_bucket)
注意:因为lifecycle删除对象是周期行执行的,删除后,则在下一个周期生效。
下面说明从rados层面如何查看bucket lifecycle:
1、查看bucket对应的rados对象:
[root@ceph06 ~]# rados -p default.rgw.meta --namespace=root ls
.bucket.meta.bk01:d9498785-8e81-41bb-aee5-312670bc75a9.14130.1
2、bucket的lc信息存在其rados对象的xattr中,key值为user.rgw.lc:
[root@ceph06 ~]# rados -p default.rgw.meta --namespace root listxattr .bucket.meta.bk01:d9498785-8e81-41bb-aee5-312670bc75a9.14130.1
user.rgw.lc
3、从bucket的rados对象中获取其lc信息:
[root@ceph06 ~]# rados -p default.rgw.meta --namespace root getxattr .bucket.meta.bk01:d9498785-8e81-41bb-aee5-312670bc75a9.14130.1 user.rgw.lc > lc
4、解码lc信息:
[root@ceph06 ~]# ceph-dencoder type RGWLifecycleConfiguration import lc decode dump_json
{
    "prefix_map": {
        "": {
            "status": true,
            "dm_expiration": false,
            "expiration": 1,
            "noncur_expiration": 0,
            "mp_expiration": 0
        }
    },
    "rule_map": [
        {
            "id": "delete-anythings-after-one-day",
            "rule": {
                "id": "delete-anythings-after-one-day",
                "prefix": "",
                "status": "Enabled",
                "expiration": {
                    "days": "1",
                    "date": ""
                },
                "noncur_expiration": {
                    "days": "",
                    "date": ""
                },
                "mp_expiration": {
                    "days": "",
                    "date": ""
                },
                "filter": {
                    "prefix": "",
                    "obj_tags": {}
                },
                "dm_expiration": false
            }
        }
    ]
}
看到bucket的lifecycle已经设置成功。上面是设置和查看bucket lc的过程,其中从rados层面去查看某个bucket的lifecycle配置步骤还是有点麻烦的。从管理层面现在貌似没法直接查看,因为radosgw-admin只提供了两个相关命令:
lc list                        list all bucket lifecycle progress
lc process                     manually process lifecycle
4、执行原理
在default.rgw.log池里面有N个lc相关的rados对象,N由配置rgw_lc_max_objs指定,默认值是32。
[root@ceph06 ~]# rados -p default.rgw.log --namespace=lc ls
lc.6
···
lc.1
lc.0
所有设置了lifecycle的bucket,会保存在这些rados对象的omap中。分配的规则是bucket名称hash和lc对象数取模。bk01被分配到了lc.10这个rados对象中,注意每个lc rados对象可以被分别多个bucket。
[root@ceph06 ~]# rados -p default.rgw.log --namespace=lc listomapkeys lc.10
:bk01:d9498785-8e81-41bb-aee5-312670bc75a9.14130.1
每个lc rados对象的omap header中记录了自己负责的,将要执行的lifecycle的bucket信息:
[root@ceph06 ~]# rados -p default.rgw.log --namespace=lc getomapheader lc.10
header (0 bytes) :
看到当前没有正在执行lc的bucket。
手动执行lc process:
[root@ceph06 ~]# radosgw-admin lc process
lifecycle执行过程:
- 设置lc执行线程最大运行时间,由配置rgw_lc_lock_max_time指定,默认60s。
- 给所选的lc对象上锁,这个lc对象是随机选择的。
- 从lc对象里面获取需要执行lifecycle的bucket。
- 更新bucket的lc状态为lc_processing。
- 更新lc对象的omap header。
- 开始遍历bucket中的所有对象的元数据,把符合条件的对象删除或转移。
- 计算下一次进入lc的时间。
查看bucket lc的状态:
[root@ceph06 ~]# radosgw-admin lc list
[
    {
        "bucket": ":bk01:d9498785-8e81-41bb-aee5-312670bc75a9.14130.1",
        "status": "UNINITIAL"
    },
    {
        "bucket": ":bk02:d9498785-8e81-41bb-aee5-312670bc75a9.14130.2",
        "status": "UNINITIAL"
    }
]
其中bucket的lc状态有四种:
UNINITIAL 未初始化
PROCESSING 进行中
FAILED 失败
COMPLETE 完成
lifecycle相关的参数:
rgw_lifecycle_work_time = "00:00-6:00"        执行lc时间窗口
rgw_enable_lc_threads = true                允许启动lc线程,设置false表示关闭lc功能
rgw_lc_lock_max_time = 60                某个lc线程每次可以执行的总时间,超过该时间没执行完,就等下次执行
rgw_lc_max_objs = 32                    lc rados对象个数
rgw_lc_max_rules = 1000                一个bucket可以设置的rule数
rgw_lc_debug_interval = -1                这个参数很关键,>0时,会忽略设置的时间窗口去执行,立即执行,并且此时设置的过期天数,1天等于1s,也就是说你设置7天后过期,此时表示7s后过期。<=0时,则按照正常的来执行。该配置主要为了方便调试lc。
注:
当数据量非常大的时候,上面说了因为是随机选择lc对象,遍历对比,所以可能有的对象没有在规定时间内删除完成,比如设置1天后过期的对象,可能会在2、3天后才删除,这个是正常的。在就是lifecycle执行过程中会对index pool的读取流量非常高,lc对系统资源消耗也比较大。
参考:
 
		